<!-- 侧边collapse选择组件 -->
<template>
  <div class="m-10px" v-if="showSearch">
    <el-input v-model="filterText" placeholder="搜索班级" clearable>
      <template #prefix>
        <Icon icon="ep:search" />
      </template>
    </el-input>
  </div>
  <el-collapse v-model="collapse as any">
    <el-collapse-item
      :name="index.toString()"
      v-for="(item, index) in filterList"
      :key="index"
      :class="{
        'is-selected': selectedKey === selectedFormat?.(item),
        'hidden-arrow': !disableTitleSelected
      }"
    >
      <template #title>
        <div
          class="w100% h100%"
          :class="{ 'w-auto': disableTitleSelected }"
          @click="handleItemClick(item, true, $event)"
        >
          {{ titleFormat?.(item) || item.label }}
        </div>
      </template>
      <div v-if="item[childrenKey] && item[childrenKey].length" class="children-list">
        <div
          v-for="(child, childIndex) in item[childrenKey]"
          :key="childIndex"
          class="el-collapse-item__header"
          :class="{
            'is-selected': selectedKey === selectedFormat?.(child)
          }"
          @click.stop="handleItemClick(child, false, $event)"
        >
          {{ childLableFormat?.(child) || child.label }}
        </div>
      </div>
    </el-collapse-item>
  </el-collapse>
</template>
<script setup lang="ts">
import { propTypes } from '@/utils/propTypes'
import { array } from 'vue-types'
const props = defineProps({
  modelValue: propTypes.string.def(''),
  // collapse展开值
  collapse: {
    type: Array,
    default: () => []
  },
  childrenKey: propTypes.string.def('children'),
  titleFormat: propTypes.func.def((item: any) => item.label),
  childLableFormat: propTypes.func.def((item: any) => item.label),
  selectedFormat: propTypes.func.def((item: any) => item.value),
  list: array<any>().def([]),
  // 是否禁用标题选中
  disableTitleSelected: propTypes.bool.def(false),
  showSearch: propTypes.bool.def(false)
})

const emit = defineEmits(['update:modelValue', 'update:collapse', 'selected-change'])
const selectedKeyBase: any = ref(0)
const filterText = ref('')
const selectedKey = computed({
  get() {
    return props.modelValue || selectedKeyBase.value
  },
  set(val) {
    emit('update:modelValue', val)
    selectedKeyBase.value = val
  }
})
const filterList = computed(() => {
  if (!filterText.value) {
    return props.list
  } else {
    return props.list.map((item) => {
      const childrenData = {}
      childrenData[props.childrenKey] = item[props.childrenKey]?.filter((child) =>
        (child.childLableFormat?.(child) || child.label)?.includes(filterText.value)
      )
      return {
        ...item,
        ...childrenData
      }
    })
  }
})
const handleItemClick = (item, isTitle?: boolean, event?: any) => {
  if (isTitle && props.disableTitleSelected) {
    return
  } else if (event && !props.disableTitleSelected) {
    // 阻止冒泡
    event.stopPropagation()
  }
  event.stopPropagation()
  const key = props?.selectedFormat?.(item)
  selectedKey.value = key
  emit('selected-change', key, item)
}
</script>
<style lang="scss" scoped>
:deep() {
  .is-selected {
    &.el-collapse-item__header,
    & > .el-collapse-item__header {
      color: var(--el-color-primary);
      background-color: color-mix(in oklch, var(--el-color-primary), transparent 94%);
    }
  }

  .hidden-arrow {
    .el-collapse-item__arrow {
      display: none;
    }
  }

  .children-item {
    height: var(--el-collapse-header-height);
  }

  .el-collapse-item__content {
    padding-bottom: 0;
  }

  .children-list {
    max-height: 288px;
    overflow-y: auto;

    .el-collapse-item__header {
      &:last-child {
        border-bottom: none;
      }
    }
  }
}
</style>
